package safrain.nodelet.node;

import java.util.StringTokenizer;

import safrain.nodelet.event.EventSource;
import safrain.nodelet.pool.PoolService;

public class NodeService {

	/**
	 * 需要对象池来缓存事件对象
	 */
	public PoolService poolService;

	public Node getChild(Node node, String name) {
		for (int i = node.children.size() - 1; i >= 0; i--) {
			Node childNode = node.children.get(i);
			if (childNode.name.equals(name)) {
				return node.children.get(i);
			}
		}
		return null;
	}

	private static final String PATH_SEPERATOR = "/";
	private static final String PATH_UPPER = "..";
	private static final String PATH_THIS = ".";

	public Node lookUp(Node node, String path) {
		Node current;
		if (path.startsWith(PATH_SEPERATOR)) {
			current = getRootNode(node);
		} else {
			current = node;
		}
		StringTokenizer tokenizer = new StringTokenizer(path, PATH_SEPERATOR);
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			Node next;
			// TODO: token为空？
			// 这个符合dos规范 ..表示父目录
			if (token.equals(PATH_UPPER)) {
				next = current.parent;
			} else if (token.equals(PATH_THIS)) {
				next = current;
			} else {
				next = getChild(current, token);
			}
			if (next == null) {
				return null;
			}
			current = next;
		}
		return current;
	}

	public boolean addChild(Node node, String name, Node child) {
		if (getChild(node, name) == null)
			return false;
		node.children.add(child);
		child.name = name;
		child.parent = node;
		child.nodeService = node.nodeService;
		dispatchNodeEvent(node.childAttachEventSource, node, child);
		return true;
	}

	public boolean removeChild(Node node, String name) {
		Node childNode;
		for (int i = node.children.size() - 1; i >= 0; i--) {
			childNode = node.children.get(i);
			if (childNode.name.equals(name)) {
				node.children.remove(i);
				childNode.name = null;
				childNode.parent = null;
				childNode.nodeService = null;
				dispatchNodeEvent(node.childDetachEventSource, node, childNode);
				return true;
			}
		}
		return false;
	}

	public Node getRootNode(Node node) {
		Node current = node;
		while (current.parent != null) {
			current = current.parent;
		}
		return current;
	}

	public Node getBrother(Node node, String name) {
		return getChild(node.parent, name);
	}

	private void dispatchNodeEvent(EventSource<NodeEvent> source, Node parent,
			Node child) {
		if (source.hasListener()) {
			NodeEvent event = poolService.get(NodeEvent.class);
			event.set(parent, child);
			source.dispatch(event);
			poolService.recycle(event);
		}
	}
}
